#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
 //permet le mapping entre le gpio est le nom d'export
static int drv_gpioGetExportName(int gpioid, char *mode) ; 


 //permet le mapping entre le gpio est le nom d'export
static int drv_gpioGetExportName(int gpioid, char *mode) 
{
	//portA
	//PA0 - PA31
	//0 - 31
	if( ( gpioid >= 0) && ( gpioid <= 31))
	{
		sprintf(mode,"pioA%d",gpioid);
	}
	//portB
	//PB11 - PB14
	//43 - 46
	else if( ( gpioid >= 43) && ( gpioid <= 46))
	{
		sprintf(mode,"pioB%d",gpioid - 32);
	}
	//portC
	//PC0 - PC31
	//64 - 95 
	else if( ( gpioid >= 64) && ( gpioid <= 95))
	{
		sprintf(mode,"pioC%d",gpioid - 64);
	}
	else
	{
		return -1;
	}
	
	return 0;
}
 
//export le gpio
int drv_gpioExport(int gpioid) 
{
	FILE *filestream;

	if ((filestream=fopen("/sys/class/gpio/export","w"))==NULL) {
		printf("Error on gpioExport \n");
		return -1;
	}	
	fprintf(filestream,"%d",gpioid);
	fclose(filestream);
	return 0;
}

//set la direction du gpio
int drv_gpioSetDir(int gpioid,char *mode) 
{
	FILE *filestream;
	char filename[50];
	char export_name[50];

	sprintf(filename,"/sys/class/gpio/");
	drv_gpioGetExportName( gpioid, export_name);
	strcat (filename,export_name);
	strcat (filename,"/direction");
	//printf("SetDir => %s\n",filename);
	if ((filestream=fopen(filename,"w"))==NULL) {
		printf("Error on gpioSetDir \n");
		return -1;
	}	
	
	fprintf(filestream, "%s",mode);
	fclose(filestream);
	return 0;
}

//etat du gpio
int drv_gpioGetBits(int gpioid) 
{
	FILE *filestream;
	char filename[50];
	char retchar;
	char export_name[50];

	sprintf(filename,"/sys/class/gpio/");
	drv_gpioGetExportName( gpioid, export_name);
	strcat (filename,export_name);
	strcat (filename,"/value");
	//printf("GetBits => %s\n",filename);
	if ((filestream=fopen(filename,"r"))==NULL) {
		printf("Error on gpioGetBits %d\n",gpioid);
		return -1;
	}	
	retchar=fgetc(filestream);
	fclose(filestream);
	if (retchar=='0') return 0;
	else return 1;
}

//set la valeur du gpio a 1
int drv_gpioSetBits(int gpioid) 
{
	FILE *filestream;
	char filename[50];
	char export_name[50];

	sprintf(filename,"/sys/class/gpio/");
	drv_gpioGetExportName( gpioid, export_name);
	strcat (filename,export_name);
	strcat (filename,"/value");
	//printf("SetBits => %s\n",filename);
	if ((filestream=fopen(filename,"w"))==NULL) {
		printf("Error on gpioSetBits %d\n",gpioid);
		return -1;
	}	
	fprintf(filestream,"1");
	fclose(filestream);
	return 0;
}

//set la valeur du gpio a 0
int drv_gpioClearBits(int gpioid) 
{
	FILE *filestream;
	char filename[50];
	char export_name[50];

	sprintf(filename,"/sys/class/gpio/");
	drv_gpioGetExportName( gpioid, export_name);
	strcat (filename,export_name);
	strcat (filename,"/value");
	//printf("ClearBits => %s\n",filename);
	if ((filestream=fopen(filename,"w"))==NULL) {
		printf("Error on gpioClearBits %d\n",gpioid);
		return -1;
	}	
	fprintf(filestream,"0");
	fclose(filestream);
	return 0;
}

//toggle la valeur du gpio a 0
int drv_gpioToggleBits(int gpioid) 
{
	if(drv_gpioGetBits(gpioid) == 0)
	{
		drv_gpioSetBits(gpioid);
	}
	else
	{
		drv_gpioClearBits(gpioid);
	}
	return 0;
}

/*int main(void) 
{
	int led_rouge = 85;
	int led_verte1 = 26;
	int led_verte2 = 27;
	int led_verte3 = 28;
	
	int i = 0 ;
	printf("Start\n"); 
	
	drv_gpioExport(led_rouge);
	drv_gpioSetDir(led_rouge,"out");
	drv_gpioExport(led_verte1);
	drv_gpioSetDir(led_verte1,"out");
	drv_gpioExport(led_verte2);
	drv_gpioSetDir(led_verte2,"out");
	drv_gpioExport(led_verte3);
	drv_gpioSetDir(led_verte3,"out");
	
	while(1)
	{
		drv_gpioSetBits(led_rouge);
		drv_gpioSetBits(led_verte1);
		drv_gpioSetBits(led_verte2);
		drv_gpioSetBits(led_verte3);
		usleep(100000);
		drv_gpioClearBits(led_rouge);
		drv_gpioClearBits(led_verte1);
		drv_gpioClearBits(led_verte2);
		drv_gpioClearBits(led_verte3);
		usleep(100000);
	}
}*/

